package fr.generali.accueilclient.gwt.client.ui.components.form.formitem;

import com.google.gwt.editor.client.EditorDelegate;
import com.google.gwt.editor.client.HasEditorDelegate;
import com.google.gwt.editor.client.LeafValueEditor;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HasValue;
import com.google.gwt.user.client.ui.TextBox;

public class IbanFormItem extends LabelFormItem<String> implements HasValue<String>, LeafValueEditor<String>,
                HasEditorDelegate<String> {

    private IbanContainer ibanContainer;

    private EditorDelegate<String> delegate;

    public IbanFormItem() {
        super(new IbanContainer());
        ibanContainer = (IbanContainer ) editableWidget;
        ibanContainer.addStyleName(res.style().ibanItem());
    }

    @Override
    public HandlerRegistration addValueChangeHandler(ValueChangeHandler<String> handler) {
        return ibanContainer.addValueChangeHandler(handler);
    }

    @Override
    public String getValue() {
        if (!validateMandatoryCriteria()) {
            delegate.recordError(ErrorType.MANDATORY.name(), null, null);
        }
        return ibanContainer.getValue();
    }

    @Override
    public void setValue(String value, boolean fireEvents) {
        setValue(value);
    }

    @Override
    protected boolean isDataFilled() {
        return ibanContainer.isDataFilled();
    }

    @Override
    protected void doSetValue(String value, boolean valueIsNullOrEmpty) {
        ibanContainer.setValue(value);
        valueLabel.setText(formatIbanWithSpaces());
    }

    private String formatIbanWithSpaces() {
        StringBuilder builder = new StringBuilder();
        builder.append(ibanContainer.getField1Value());
        addSpaceIfNextIsNotEmpty(builder, ibanContainer.getField2Value());
        builder.append(ibanContainer.getField2Value());
        addSpaceIfNextIsNotEmpty(builder, ibanContainer.getField3Value());
        builder.append(ibanContainer.getField3Value());
        addSpaceIfNextIsNotEmpty(builder, ibanContainer.getField4Value());
        builder.append(ibanContainer.getField4Value());
        addSpaceIfNextIsNotEmpty(builder, ibanContainer.getField5Value());
        builder.append(ibanContainer.getField5Value());
        addSpaceIfNextIsNotEmpty(builder, ibanContainer.getField6Value());
        builder.append(ibanContainer.getField6Value());
        addSpaceIfNextIsNotEmpty(builder, ibanContainer.getField7Value());
        builder.append(ibanContainer.getField7Value());
        addSpaceIfNextIsNotEmpty(builder, ibanContainer.getField8Value());
        builder.append(ibanContainer.getField8Value());
        addSpaceIfNextIsNotEmpty(builder, ibanContainer.getField9Value());
        builder.append(ibanContainer.getField9Value());
        return builder.toString();
    }

    private void addSpaceIfNextIsNotEmpty(StringBuilder builder, String next) {
        if (!next.isEmpty()) {
            builder.append(" ");
        }
    }

    @Override
    protected boolean valueIsNullOrEmpty(String value) {
        return value == null || value.isEmpty();
    }
    
    public void setRefFrancaise(boolean bRefFrancaise) {
        ibanContainer.setRefFrancaise(bRefFrancaise);
    }

    public boolean isIbanFilled() {
        return ibanContainer.isIbanFilled();
    }

    public boolean isIbanEmpty() {
        return ibanContainer.isIbanEmpty();
    }

    public String getIban1() {
        return ibanContainer.getField1Value();
    }

    public String getIban2() {
        return ibanContainer.getField2Value();
    }

    public String getIban3() {
        return ibanContainer.getField3Value();
    }

    public String getIban4() {
        return ibanContainer.getField4Value();
    }

    public String getIban5() {
        return ibanContainer.getField5Value();
    }

    public String getIban6() {
        return ibanContainer.getField6Value();
    }

    public String getIban7() {
        return ibanContainer.getField7Value();
    }

    public String getIban8() {
        return ibanContainer.getField8Value();
    }

    public String getIban9() {
        return ibanContainer.getField9Value();
    }

    private static class IbanContainer extends FlowPanel {

        private TextBox field1;

        private TextBox field2;

        private TextBox field3;

        private TextBox field4;

        private TextBox field5;

        private TextBox field6;

        private TextBox field7;

        private TextBox field8;

        private TextBox field9;

        public IbanContainer() {

            field1 = createTextBox(4, "30px");
            field2 = createTextBox(4, "30px");
            field3 = createTextBox(4, "30px");
            field4 = createTextBox(4, "30px");
            field5 = createTextBox(4, "30px");
            field6 = createTextBox(4, "30px");
            field7 = createTextBox(4, "30px");
            field8 = createTextBox(4, "30px");
            field9 = createTextBox(3, "30px");

            add(field1);
            add(field2);
            add(field3);
            add(field4);
            add(field5);
            add(field6);
            add(field7);
            add(field8);
            add(field9);

            this.setWidth("310px");
            
            field1.addKeyUpHandler(new KeyUpHandler() {
				
				@Override
				public void onKeyUp(KeyUpEvent event) {
					if (field1.getValue().length() == 4) {
						field2.setFocus(true);
					}
					field1.setValue(field1.getValue().toUpperCase());
				}
			});
            
            field2.addKeyUpHandler(new KeyUpHandler() {
				
				@Override
				public void onKeyUp(KeyUpEvent event) {
					if (field2.getValue().length() == 4) {
						field3.setFocus(true);
					}
					field2.setValue(field2.getValue().toUpperCase());
				}
			});
            
            field3.addKeyUpHandler(new KeyUpHandler() {
				
				@Override
				public void onKeyUp(KeyUpEvent event) {
					if (field3.getValue().length() == 4) {
						field4.setFocus(true);
					}
					field3.setValue(field3.getValue().toUpperCase());
				}
			});
            
            field4.addKeyUpHandler(new KeyUpHandler() {
				
				@Override
				public void onKeyUp(KeyUpEvent event) {
					if (field4.getValue().length() == 4) {
						field5.setFocus(true);
					}
					field4.setValue(field4.getValue().toUpperCase());
				}
			});

            field5.addKeyUpHandler(new KeyUpHandler() {
				
				@Override
				public void onKeyUp(KeyUpEvent event) {
					if (field5.getValue().length() == 4) {
						field6.setFocus(true);
					}
					field5.setValue(field5.getValue().toUpperCase());
				}
			});
            
            field6.addKeyUpHandler(new KeyUpHandler() {
				
				@Override
				public void onKeyUp(KeyUpEvent event) {
					if (field6.getValue().length() == 4) {
						field7.setFocus(true);
					}
					field6.setValue(field6.getValue().toUpperCase());
				}
			});

            field7.addKeyUpHandler(new KeyUpHandler() {
				
				@Override
				public void onKeyUp(KeyUpEvent event) {
					if (field7.getValue().length() == 4) {
						field8.setFocus(true);
					}
					field7.setValue(field7.getValue().toUpperCase());
				}
			});
            
            field8.addKeyUpHandler(new KeyUpHandler() {
				
				@Override
				public void onKeyUp(KeyUpEvent event) {
					if (field8.getValue().length() == 4) {
						field9.setFocus(true);
					}
					field8.setValue(field8.getValue().toUpperCase());
				}
			});
            
            field9.addKeyUpHandler(new KeyUpHandler() {
				
				@Override
				public void onKeyUp(KeyUpEvent event) {
					field9.setValue(field9.getValue().toUpperCase());
				}
			});
            
        }

        public String getField9Value() {
            return field9.getValue();
        }

        public String getField8Value() {
            return field8.getValue();
        }

        public String getField7Value() {
            return field7.getValue();
        }

        public String getField6Value() {
            return field6.getValue();
        }

        public String getField5Value() {
            return field5.getValue();
        }

        public String getField4Value() {
            return field4.getValue();
        }

        public String getField3Value() {
            return field3.getValue();
        }

        public String getField2Value() {
            return field2.getValue();
        }

        public String getField1Value() {
            return field1.getValue();
        }

        public void setValue(String value) {
            if (value != null) {
                setFieldValue(field1, value, 0);
                setFieldValue(field2, value, 4);
                setFieldValue(field3, value, 8);
                setFieldValue(field4, value, 12);
                setFieldValue(field5, value, 16);
                setFieldValue(field6, value, 20);
                setFieldValue(field7, value, 24);
                setFieldValue(field8, value, 28);
                setFieldValue(field9, value, 32);
            }
        }

        private void setFieldValue(TextBox field, String value, int startIndex) {
            if (value.length() > startIndex) {
                field.setValue(value.substring(startIndex, Math.min(startIndex + 4, value.length())));
            } else {
                field.setValue("");
            }
        }

        public String getValue() {
            StringBuilder builder = new StringBuilder();
            builder.append(field1.getValue());
            builder.append(field2.getValue());
            builder.append(field3.getValue());
            builder.append(field4.getValue());
            builder.append(field5.getValue());
            builder.append(field6.getValue());
            builder.append(field7.getValue());
            builder.append(field8.getValue());
            builder.append(field9.getValue());
            return builder.toString();
        }

        public HandlerRegistration addValueChangeHandler(ValueChangeHandler<String> handler) {
            field1.addValueChangeHandler(handler);
            field2.addValueChangeHandler(handler);
            field3.addValueChangeHandler(handler);
            field4.addValueChangeHandler(handler);
            field5.addValueChangeHandler(handler);
            field6.addValueChangeHandler(handler);
            field7.addValueChangeHandler(handler);
            field8.addValueChangeHandler(handler);
            return field9.addValueChangeHandler(handler);
        }

        private TextBox createTextBox(int maxLegnth, String width) {
            TextBox box = new TextBox();
            box.setMaxLength(maxLegnth);
            box.setWidth(width);
            return box;
        }

        @Override
        public void addStyleName(String styleName) {
            field1.addStyleName(styleName);
            field2.addStyleName(styleName);
            field3.addStyleName(styleName);
            field4.addStyleName(styleName);
            field5.addStyleName(styleName);
            field6.addStyleName(styleName);
            field7.addStyleName(styleName);
            field8.addStyleName(styleName);
            field9.addStyleName(styleName);
        }

        @Override
        public void removeStyleName(String styleName) {
            field1.removeStyleName(styleName);
            field2.removeStyleName(styleName);
            field3.removeStyleName(styleName);
            field4.removeStyleName(styleName);
            field5.removeStyleName(styleName);
            field6.removeStyleName(styleName);
            field7.removeStyleName(styleName);
            field8.removeStyleName(styleName);
            field9.removeStyleName(styleName);
        }

        boolean isDataFilled() {
            return !isIbanEmpty();
        }

        public boolean isIbanFilled() {
            boolean isComplet = true;
            int tailleIban = 4;

            isComplet = isComplet && !field1.getValue().isEmpty() && (field1.getValue().length() == tailleIban);
            isComplet = isComplet && !field2.getValue().isEmpty() && (field2.getValue().length() == tailleIban);
            isComplet = isComplet && !field3.getValue().isEmpty() && (field3.getValue().length() == tailleIban);
            isComplet = isComplet && !field4.getValue().isEmpty() && (field4.getValue().length() == tailleIban);
            isComplet = isComplet && !field5.getValue().isEmpty() && (field5.getValue().length() == tailleIban);
            isComplet = isComplet && !field6.getValue().isEmpty() && (field6.getValue().length() == tailleIban);
            isComplet = isComplet && !field7.getValue().isEmpty() && (field7.getValue().length() == 3);

            return isComplet;
        }

        public boolean isIbanEmpty() {
            boolean isVide = true;

            isVide = isVide && field1.getValue().isEmpty();
            isVide = isVide && field2.getValue().isEmpty();
            isVide = isVide && field3.getValue().isEmpty();
            isVide = isVide && field4.getValue().isEmpty();
            isVide = isVide && field5.getValue().isEmpty();
            isVide = isVide && field6.getValue().isEmpty();
            isVide = isVide && field7.getValue().isEmpty();
            isVide = isVide && field8.getValue().isEmpty();
            isVide = isVide && field9.getValue().isEmpty();

            return isVide;
        }
        
        public void setRefFrancaise(boolean bRefFrancaise) {
            if (bRefFrancaise) {
            	field8.setVisible(false);
            	field9.setVisible(false);
            } else {
            	field8.setVisible(true);
            	field9.setVisible(true);
            }
        }
    }

    @Override
    public void setDelegate(EditorDelegate<String> delegate) {
        this.delegate = delegate;
    }

}
